home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PB_212.ZIP / CPPDATE.CPP < prev    next >
C/C++ Source or Header  |  1995-09-09  |  5KB  |  259 lines

  1. #include <pb_sdk.h>
  2. #include "cppdate.hpp"
  3.  
  4. struct fdate
  5.    {
  6.       word day   : 5;   /* Days */
  7.       word month : 4;   /* Months */
  8.       word year  : 7;   /* Year */
  9.    };
  10.  
  11.  
  12. /////////////////////////////////////////////////////////////////////////////
  13. // Calculates the number of days BEFORE the first of a given month         //
  14. /////////////////////////////////////////////////////////////////////////////
  15.  
  16. static int
  17. months_to_days(int month)
  18. {
  19.    return int (l_div((l_mul(month , 3057) - 3007) , 100));
  20. }
  21.  
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24. // Calculates the number of days in a given number of years since 1-1-0001 //
  25. /////////////////////////////////////////////////////////////////////////////
  26.  
  27. static long
  28. years_to_days(int yr)
  29. {
  30.    return l_mul(yr , 365L) + yr / 4 - yr / 100 + yr / 400;
  31. }
  32.  
  33.  
  34. Date::Date()
  35. {
  36.    _d = _m = _y = 0;
  37. }
  38.  
  39. Date::Date(int d,int m,int y)
  40. {
  41.    _d = d;
  42.    _m = m;
  43.    _y = y;
  44. }
  45.  
  46. Date::Date(long val)
  47. {
  48.    if(val < 0)
  49.    {
  50.       today();
  51.    }
  52.    else
  53.    {
  54.       (*this) = val;
  55.    }
  56. }
  57.  
  58. char *Date::weekdays[7]   = { "Mon","Tue","Wed","Thu","Fri","Sat","Sun" };
  59. char *Date::s_weekdays[7] = { "Mo","Tu","We","Th","Fr","Sa","Su" };
  60. char *Date::l_weekdays[7] = { "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday" };
  61. char *Date::months[12]    = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
  62. char *Date::l_months[12]  = { "January","February","March","April","May","June","July","August","September","October","November","December" };
  63.  
  64. void
  65. Date::today()
  66. {
  67.    time_t tm_val = time(NULL);
  68.  
  69.    struct tm *tm_struct = localtime(&tm_val);
  70.  
  71.    _d = tm_struct->tm_mday;
  72.    _m = tm_struct->tm_mon + 1;
  73.    _y = tm_struct->tm_year;
  74. }
  75.  
  76. void
  77. Date::set(int day,int month,int year)
  78. {
  79.    _d = day;
  80.    _m = month;
  81.    _y = (year>1900) ? (year-1900) : year;
  82. }
  83.  
  84. char&
  85. Date::operator[](int i)
  86. {
  87.    switch(i)
  88.    {
  89.       case 0 : return _d;
  90.       case 1 : return _m;
  91.       default: return _y;
  92.    }
  93. }
  94.  
  95. int
  96. Date::compare(Date& dt) const
  97. {
  98.    if(_y - dt._y) return (_y - dt._y);
  99.    if(_m - dt._m) return (_m - dt._m);
  100.    if(_d - dt._d) return (_d - dt._d);
  101.  
  102.    return 0;
  103. }
  104.  
  105. int
  106. Date::operator<(Date& d) const
  107. {
  108.    return (compare(d) < 0);
  109. }
  110.  
  111. int
  112. Date::operator>(Date& d) const
  113. {
  114.    return (compare(d) > 0);
  115. }
  116.  
  117. int
  118. Date::operator==(Date& d) const
  119. {
  120.    return (compare(d) == 0);
  121. }
  122.  
  123. int
  124. Date::operator!=(Date& d) const
  125. {
  126.    return compare(d);
  127. }
  128.  
  129. int
  130. Date::operator>=(Date& d) const
  131. {
  132.    return (compare(d) >= 0);
  133. }
  134.  
  135. int
  136. Date::operator<=(Date& d) const
  137. {
  138.    return (compare(d) <= 0);
  139. }
  140.  
  141. bool
  142. Date::ok() const
  143. {
  144.    return !(_d<1 || _m<1 || _m>12 || _y<0 || _d>daysInMonth());
  145. }
  146.  
  147. bool
  148. Date::leap() const
  149. {
  150.    int yr = _y + 1900;
  151.  
  152.    return ( yr%4 == 0 && yr%100 != 0 || yr%400 == 0 );
  153. }
  154.  
  155. int
  156. Date::weekDay() const
  157. {
  158.    return int( l_mod((long(*this)-1) , 7));
  159. }
  160.  
  161. int
  162. Date::weekNum() const
  163. {
  164.    Date nyd(1,1,_y);
  165.  
  166.    int w = (dayNum() + nyd.weekDay() - 1)/7 + (nyd.weekDay() < 4);
  167.  
  168.    return ((w < 1) ? weeksInYear(_y-1) : w);
  169. }
  170.  
  171. int
  172. Date::weeksInYear(int y) const
  173. {
  174.    if(!y) y = _y;
  175.  
  176.    return Date(31,12,y).weekNum();
  177. }
  178.  
  179.  
  180. Date&
  181. Date::operator=(long julian)
  182. {
  183.    int n;                /* compute inverse of years_to_days() */
  184.  
  185.    for ( n = int(l_div(l_mul(julian , 400L) , 146097L)); years_to_days(n) < julian;) n++;
  186.  
  187.    _y = n - 1900;
  188.  
  189.    n = int(julian - years_to_days(n-1));
  190.  
  191.    if( n > 59 )
  192.    {
  193.       n += 2;
  194.  
  195.       if( leap() )  n -= (n > 62) ? 1 : 2;
  196.    }
  197.  
  198.    _m = int(l_div((l_mul(n , 100) + 3007) , 3057));
  199.  
  200.    _d = n - months_to_days(_m);
  201.  
  202.    return *this;
  203. }
  204.  
  205. int
  206. Date::dayNum() const
  207. {
  208.    int days = months_to_days(_m);
  209.  
  210.    if(_m>2)
  211.    {
  212.       days -= leap() ? 1:2;
  213.    }
  214.  
  215.    return days + _d;
  216. }
  217.  
  218. Date::operator long() const
  219. {
  220.    return years_to_days(_y+1899) + dayNum();
  221. }
  222.  
  223. int
  224. Date::operator-(Date &d) const
  225. {
  226.    return int(long(*this) - long(d));
  227. }
  228.  
  229. void
  230. Date::fileDate(word x)
  231. {
  232.     fdate fd;
  233.  
  234.     *((word *)(&fd)) = x;
  235.  
  236.     _d = fd.day;
  237.     _m = fd.month;
  238.     _y = fd.year+80;
  239. }
  240.  
  241.  
  242. int
  243. Date::daysInMonth(int m) const
  244. {
  245.    static int months[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  246.  
  247.    if(!m) m = _m;
  248.  
  249.    return months[m-1] + (leap() && m==2);
  250. }
  251.  
  252. int
  253. Date::daysInYear(int y) const
  254. {
  255.    if(!y) y = _y;
  256.  
  257.    return 365 + Date(1,1,y).leap();
  258. }
  259.